package io.gitee.icefairy.total_monitor.service

import cn.hutool.core.date.DateUtil
import cn.hutool.db.Db
import cn.hutool.db.Entity
import cn.hutool.db.Page
import io.gitee.icefairy.total_monitor.model.RetObj
import io.gitee.icefairy.total_monitor.repo.ItemRepo
import io.gitee.icefairy.total_monitor.task.ActiveLogTask
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.data.domain.Pageable
import org.springframework.stereotype.Service

import java.util.*

/**
 * AUTHOR:icefairy
 * DATE:2021/12/13 0013 13:47
 **/
interface MonitorServiceDef {
    fun active(id: String, status: Int, extra: String?, note: String?, client: String?): RetObj
    fun list(pa: Pageable): RetObj
}

@Service
open class MonitorService : MonitorServiceDef {
    @Autowired
    lateinit var db: Db

    @Value("\${tm.heart}")
    var heart = 15

    @Autowired
    lateinit var ir: ItemRepo
    override fun active(id: String, status: Int, extra: String?, note: String?, client: String?): RetObj {
        db.update(
            Entity.create("z_item")
                .set("extra", extra ?: "")
                .set("note", note ?: "")
                .set("last_active", Date())
                .set("status", status)
                .set("ip", client ?: ""),
            Entity.create("z_item").set("id", id.toLong())
        )
        GlobalScope.async {
            ActiveLogTask.chnLogs.send(
                Entity.create("z_active_log")
                    .set("create_date", Date())
                    .set("item_id", id.toLong())
                    .set("status", status)
                    .set("ip", client ?: "")
            )
        }
        return RetObj(200, "更新状态成功", "")
    }

    override fun list(pa: Pageable): RetObj {
        val p = db.page(
            "select * from z_item order by status,group_set,project,last_active asc",
            Page(pa.pageNumber - 1, pa.pageSize)
        )
        return RetObj(200, mapOf("items" to p.toList().map {
            val lastactive = it.getDate("last_active")
            if (lastactive != null) {
                val liveDate=DateUtil.offsetMinute(Date(),-heart).toJdkDate()
                if (liveDate.after(lastactive)){
                    /**
                     *如果最晚允许检测时间晚于最后活跃时间则认为掉线（至少15分钟没有收到活跃请求）
                     * 避免出现几小时前活跃过传来的status为1造成状态持续为1的情况
                     */
                    it.set("status", 0)
                }
            } else {
                it.set("status", 0)
            }
            it.set("note",it.getClob("note")?.characterStream?.readText()?:"")
            it.set("extra",it.getClob("extra")?.characterStream?.readText()?:"")
            it
        }, "total" to p.total), "")
    }
}